<?php


class IContext extends IMagicObject implements ArrayAccess {
	private static $instance;
	
	private function __construct() {
		
	}
	
	/**
	 * Enter description here...
	 *
	 * @return IContext
	 */
	public static function singleton() {
		if (self::$instance == null) {
			self::$instance = new self;
		}
		return self::$instance;
	}
	
	private function type(&$key) {
		$key = strval($key);
		if (strlen($key) <= 1) {
			return "request";
		}
		$prefix = $key{0};
		if (in_array($prefix, array("!", "#", "*", "%"))) {
			$key = substr($key, 1);
			switch ($prefix) {
				case "!":
					return "flash";
				case "#":
					return "session";
				case "*":
					return "cookie";
				case "%":
					return "request";
			}
		}
		return "request";
	}
	
	/**
	 * Enter description here...
	 *
	 * @return IFlash
	 */
	public function flash() {
		return IFlash::singleton();
	}
	
	/**
	 * Enter description here...
	 *
	 * @return ISession
	 */
	public function session() {
		return ISession::singleton();
	}
	
	/**
	 * Enter description here...
	 *
	 * @return IRequest
	 */
	public function request() {
		return IRequest::singleton();
	}
	
	/**
	 * Enter description here...
	 *
	 * @return IResponse
	 */
	public function response() {
		return IResponse::singleton();
	}
	
	/**
	 * 判断键是否存在
	 * 
	 * 使用 isset($object[$key]) 时激活
	 *
	 * @param mixed $key 键
	 * @return boolean
	 * @since 0.0.3
	 */
	public function offsetExists($key) {
		switch ($this->type($key)) {
			case "flash":
				return $this->flash()->contains($key);
			case "session":
				return $this->session()->contains($key);
			case "cookie":
				return ICookie::get($key) != null;
			case "request":
				return $this->request()->param($key) != null;
		}
		return false;
	}
	
	/**
	 * 取得键的值
	 * 
	 * 使用 echo $object[$key] 时激活
	 *
	 * @param mixed $key 键
	 * @return mixed
	 * @since 0.0.3
	 */
	public function offsetGet($key) {
		switch ($this->type($key)) {
			case "flash":
				return $this->flash()->get($key);
			case "session":
				return $this->session()->get($key);
			case "cookie":
				return ICookie::get($key);
			case "request":
				return $this->request()->param($key);
		}
		return $this->request()->param($key);
	}
	
	
	/**
	 * 设置键的值
	 * 
	 * 使用 $object[$key] = $value; 时激活
	 *
	 * @param mixed $key 键
	 * @param mixed $item 键的值
	 * @since 0.0.3
	 */	
	public function offsetSet($key, $item) {
		switch ($this->type($key)) {
			case "flash":
				$this->flash()->set($key, $item);
				break;
			case "session":
				$this->session()->set($key, $item);
				break;
			case "cookie":
				$cookie = new ICookie($key, $item);
				$cookie->setPath("/");
				$cookie->send();
				break;
			case "request":
				$this->request()->addParam($key, $item);
				break;
			default:
				$this->request()->addParam($key, $item);
		}
	}
	
	/**
	 * 销毁键对应的元素
	 * 
	 * 使用 unnset($object[$key]) 时激活
	 *
	 * @param mixed $key 键
	 * @since 0.0.3
	 */
	public function offsetUnset($key) {
		switch ($this->type($key)) {
			case "flash":
				$this->flash()->remove($key);
				break;
			case "session":
				$this->session()->remove($key);
				break;
			case "cookie":
				$cookie = new ICookie($key, null);
				$cookie->setMaxAge(-1);
				$cookie->setPath("/");
				$cookie->send();
				break;
			case "request":
				$this->request()->remove($key);
				break;
			default:
				$this->request()->remove($key);
		}
	}
	
	public function __get($name) {
		$value = null;
		try {
			$value = parent::__get($name);
		} catch (IException $e) {
			
		}
		if ($value === null) {
			$value = $this->request()->param($name);
		}
		return $value;
	}
}

?>